package com.dataseek.iot.sys.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.dataseek.iot.sys.utils.MetadataConsts;
import com.dataseek.iot.sys.entity.*;
import com.dataseek.iot.sys.mapper.*;
import com.dataseek.iot.sys.service.DbService;
import com.dataseek.iot.sys.utils.GetChildUtil;
import com.dataseek.iot.sys.vo.MenuVo;
import com.dataseek.iot.toolikit.common.util.DBUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @discription:
 * @author: Freya.Yan
 * @date: 2022/3/12
 */
@Service
@Slf4j
public class DbserviceImpl implements DbService {

    @Autowired
    private TenantSysUserMapper tenantSysUserMapper;

    @Autowired
    private UserRoleMapper userRoleMapper;

    @Autowired
    private RoleMapper roleMapper;

    @Autowired
    private MenuMapper menuMapper;

    @Autowired
    private RoleMenuMapper roleMenuMapper;

    @Override
    public Integer createDb(String dbType, String databaseName) {
        int resultCode = 0;
        Connection connection = DBUtils.getConnection(
                dbType,
                MetadataConsts.pgHost,
                MetadataConsts.pgPort,
                "postgres",
                MetadataConsts.pgUsername,
                MetadataConsts.pgPassword
        );
        if (connection != null) {
            String sql = "CREATE DATABASE {0};";
            sql = MessageFormat.format(sql, databaseName);
            resultCode = DBUtils.execute(connection, sql);
        }

        Connection connectionDb = DBUtils.getConnection(
                dbType,
                MetadataConsts.pgHost,
                MetadataConsts.pgPort,
                databaseName,
                MetadataConsts.pgUsername,
                MetadataConsts.pgPassword
        );

        if (connectionDb != null) {
            String sql2 = "CREATE SCHEMA tenant;";
            resultCode = DBUtils.execute(connectionDb, sql2);
        }

        return resultCode;
    }

    @Override
    public Integer createDbTables(String dbType, Tenant tenant) throws SQLException {
        String databaseName = tenant.getCompanyCode();
        String tenantName = tenant.getTenantName();
        int resultCode = 0;
        String pwEnCode = new String();

        Connection connection = DBUtils.getConnection(
                dbType,
                MetadataConsts.pgHost,
                MetadataConsts.pgPort,
                databaseName,
                MetadataConsts.pgUsername,
                MetadataConsts.pgPassword
        );
        if (connection != null) {
            resultCode = DBUtils.batchTableCreate(connection, databaseName);
        }

        Connection connectionMaster = DBUtils.getConnection(
                dbType,
                MetadataConsts.pgHost,
                MetadataConsts.pgPort,
                "postgres",
                MetadataConsts.pgUsername,
                MetadataConsts.pgPassword
        );
        List<Map<String, Object>> resultList = new ArrayList<>();
        List<Map<String, Object>> resultListMenu = new ArrayList<>();
        if (connectionMaster != null) {
            String tenantSql = "select * from tenant.sys_tenant where company_code = {0}";
            tenantSql = MessageFormat.format(tenantSql, "'" + databaseName + "'");
            ResultSet rs = DBUtils.query(connectionMaster, tenantSql);
            resultList = DBUtils.formatDatabaseData(rs);

            String menuSql = "select * from tenant.sys_menu where is_uniq = {0}";
            menuSql = MessageFormat.format(menuSql, "'" + "1" + "'");
            ResultSet rsMenu = DBUtils.query(connectionMaster, menuSql);
            resultListMenu = DBUtils.formatDatabaseData(rsMenu);
        }
        connectionMaster.close();
        Connection connection2 = DBUtils.getConnection(
                dbType,
                MetadataConsts.pgHost,
                MetadataConsts.pgPort,
                databaseName,
                MetadataConsts.pgUsername,
                MetadataConsts.pgPassword
        );
        log.info("resultList:" + resultList);
        for (int i = 0; i < resultList.size(); i++) {
            Map<String, Object> stringObjectMap = resultList.get(i);
            pwEnCode = String.valueOf(stringObjectMap.get("tenant_password"));
            resultCode = DBUtils.insertTenant(connection2, stringObjectMap);
        }
        Connection connection3 = DBUtils.getConnection(
                dbType,
                MetadataConsts.pgHost,
                MetadataConsts.pgPort,
                databaseName,
                MetadataConsts.pgUsername,
                MetadataConsts.pgPassword
        );

        DBUtils.insertMenu(connection3, resultListMenu, databaseName);
        Connection connection4 = DBUtils.getConnection(
                dbType,
                MetadataConsts.pgHost,
                MetadataConsts.pgPort,
                databaseName,
                MetadataConsts.pgUsername,
                MetadataConsts.pgPassword
        );
        resultCode = DBUtils.batchTableInsert(connection4, databaseName, tenantName, pwEnCode);
        return resultCode;

    }

    @Override
    public List<String> queryPermissions(String userName) {
        List<Menu> listMenu = new ArrayList<>();
        List<String> list = new ArrayList<>();
        List<MenuVo> rootlist = new ArrayList<>();
        QueryWrapper<TenantSysUser> qwUser = new QueryWrapper<>();
        qwUser.eq("user_name", userName);
        TenantSysUser tenantSysUser = tenantSysUserMapper.selectOne(qwUser);
        if (tenantSysUser != null) {
            long userId = tenantSysUser.getUserId();
            QueryWrapper<UserRole> qwUserRole = new QueryWrapper<>();
            qwUserRole.eq("user_id", userId);
            UserRole userRole = userRoleMapper.selectOne(qwUserRole);
            if (userRole != null) {
                long roleId = userRoleMapper.selectOne(qwUserRole).getRoleId();
                QueryWrapper<RoleMenu> qwRoleMenu = new QueryWrapper<>();
                qwRoleMenu.eq("role_id", roleId);
                List<RoleMenu> roleMenus = roleMenuMapper.selectList(qwRoleMenu);
                for (int i = 0; i < roleMenus.size(); i++) {
                    long menuId = roleMenus.get(i).getMenuId();
                    QueryWrapper<Menu> qwMenu = new QueryWrapper<>();
                    qwMenu.eq("menu_id", menuId);
                    Menu menu = menuMapper.selectOne(qwMenu);
                    if (!"F".equals(menu.getMenuType())) {
                        listMenu.add(menu);
                    } else {
                        String path = menu.getPath();
                        list.add(path);
                    }
                }
                for (Menu menu : listMenu) {
                    if (menu.getParentId() == null || "".equals(menu.getParentId()) || "0".equals(menu.getParentId())) {
                        MenuVo menuVo = new MenuVo();
                        menuVo.setMenuId(menu.getMenuId());
                        menuVo.setMenuName(menu.getMenuName());
                        menuVo.setMenuType(menu.getMenuType());
                        menuVo.setIcon(menu.getIcon());
                        menuVo.setStatus(menu.getStatus());
                        menuVo.setParentId(menu.getParentId());
                        menuVo.setOrderNum(menu.getOrderNum());
                        menuVo.setPath(menu.getPath());
                        menuVo.setPerms(menu.getPerms());
                        //找到根节点菜单的时候，寻找这个根节点菜单下的子节点菜单。
                        GetChildUtil.findChilds(menuVo, listMenu);
                        //添加到根节点的列表中
                        rootlist.add(menuVo);
                    }
                }
                for (int m = 0; m < rootlist.size(); m++) {
                    MenuVo menuVo = rootlist.get(m);
                    String menu = JSONObject.toJSONString(menuVo);
                    //String menu = menuVo.toString();
                    list.add(menu);
                }
            }
        }
        return list;


    }

}
